package org.finmanager.data;

import org.finmanager.core.Item;
import org.finmanager.core.Category;

import java.io.File;
import java.io.PrintWriter;
import java.util.*;

import static org.finmanager.core.Constants.MAIN_DATA_FILE_NAME;

/**
 * Created by Kelvin on 21/3/2014.
 * <p/>
 * This is an abstract list containing Items
 * <p/>
 * This class supports load/save items from data file,
 * add/edit/delete an item from the list,
 * delete all items of a certain category and
 * find an item with given attributes
 */

//In our system, each item(financial record) is stored as LIST in a .txt file

public class ItemList {
	private ArrayList<Item> list = new ArrayList<Item>();
	private CategoryList categoryList;

	public ItemList(CategoryList categoryList) {
		this.categoryList = categoryList;

		loadFile();
	}

	// Load items from the data file and store each item to a list
	// Currently we use .txt file for storage
	// This method is called at the start of the program
	private void loadFile() {
		try {
			File file = new File(MAIN_DATA_FILE_NAME);

			// Create a new file if one does not exist
			// Add a zero to this new file (important)
			if (file.createNewFile()) {
				PrintWriter writer = new PrintWriter(file);
				writer.println(0);
				writer.close();
			}

			Scanner scanner = new Scanner(file);

			int numOfItems = Integer.parseInt(scanner.nextLine());
			for (int i = 0; i < numOfItems; ++i) {
				String name = scanner.nextLine();

				int year = Integer.parseInt(scanner.nextLine());
				int month = Integer.parseInt(scanner.nextLine());
				int dayOfMonth = Integer.parseInt(scanner.nextLine());

				double amount = Double.parseDouble(scanner.nextLine());

				String categoryName = scanner.nextLine();
				Category category = categoryList.findCategory(categoryName);

				Item item = new Item(name, year, month, dayOfMonth, amount, category);
				list.add(item);
			}
			scanner.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// Save each items on the list to data file
	// PrintWriter always overwrite previous data
	// This method is called every time when the list is changed
	private void saveFile() {
		try {
			File file = new File(MAIN_DATA_FILE_NAME);
			file.createNewFile();

			PrintWriter writer = new PrintWriter(file);

			writer.println(list.size());
			for (Item item : list) {
				writer.println(item.getName());
				writer.println(item.getDate().get(Calendar.YEAR));
				writer.println(item.getDate().get(Calendar.MONTH));
				writer.println(item.getDate().get(Calendar.DAY_OF_MONTH));
				writer.println(item.getAmount());
				writer.println(item.getCategory().getName());
			}
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//add item
	public void addItem(Item item) {
		list.add(item);
		saveFile();
	}
	
	//delete item
	public void deleteItem(int index) {
		list.remove(index);
		saveFile();
	}

	// Delete all items with a certain category
	// This method is called when a category is deleted
	public void deleteItemsWithCategory(Category category) {
		ArrayList<Item> itemsToRemoved = new ArrayList<Item>();
		for (Item item : list) {
			if (item.getCategory().equals(category)) {
				itemsToRemoved.add(item);
			}
		}

		for (Item item : itemsToRemoved) {
			list.remove(item);
		}
		saveFile();
	}
	
	//count how many exiting items
	public int getItemCount() {
		return list.size();
	}
	
	//get a specific item
	public Item getItem(int index) {
		return list.get(index);
	}
	
	//replacement(correction) of an item
	public void setItem(int index, Item item) {
		list.set(index, item);
		saveFile();
	}

	public List<Item> getList() {
		return Collections.unmodifiableList(list);
	}
}
